package com.xjzd.std.concurrency;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

public class ThreadPoolMemoryLeakDemo {

    static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
            2, 2, 5,
            TimeUnit.SECONDS, new LinkedBlockingDeque<>(1),
            new CustomRejectedPolicy()
    );

    public static final class CustomRejectedPolicy implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
            System.out.println("发生了自定义拒绝策略");
            if (r instanceof FutureTask<?> futureTask) {
                System.out.println("任务状态: " + futureTask);
            }

            // 如果不抛出异常，被阻塞的任务线程将不会被唤醒
            throw new RejectedExecutionException("任务被拒绝执行");
        }
    }

    public static final class MyTask {
        private final Integer stockCount;

        private final Integer index;

        public MyTask(int taskId) {
            this.stockCount = new Random().nextInt(100);
            this.index = taskId;
        }

        public Integer doIt() {
            Integer result = stockCount * index;
            System.out.println("计算结果: " + result);
            return result;
        }
    }

    public static void doExample(ThreadPoolExecutor threadPool) {
        try {
            List<Future<Integer>> futures = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                MyTask myTask = new MyTask(i);
                Future<Integer> future = threadPool.submit(myTask::doIt);
                futures.add(future);
            }

            for (Future<Integer> future : futures) {
                System.out.println("任务结果: " + future.get());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            Thread.sleep(100);
            new Thread(() -> {
                doExample(threadPool);
            }).start();
        }
    }
}
